#include "server.hpp"


// void HandleClose(Channel *chn)
// {
//     chn->Remove();
//     int fd = chn->Fd();
//     close(fd);
// }

// void HandleRead(Channel *chn)
// {
//     int fd = chn->Fd();
//     char buffer[1024];
//     int ret = recv(fd, buffer, sizeof(buffer), 0);
//     if (ret < 0)
//     {
//         ERR_LOG("HandleRead Error, fd : %d", fd);
//         HandleClose(chn);
//         return;
//     }
//     else if (ret == 0)
//     {
//         ERR_LOG("recv 0 character, close fd : %d", fd);
//         HandleClose(chn);
//         return;
//     }
//     buffer[ret] = 0;
//     DBG_LOG("%s", buffer);
//     chn->EnableWrite();
// }

// void HandleWrite(Channel *chn)
// {
//     int fd = chn->Fd();
//     std::string str = "hello world";
//     int ret = send(fd, str.c_str(), str.size(), 0);
//     if (ret < 0)
//     {
//         ERR_LOG("HandleWrite Error, fd : %d", fd);
//         HandleClose(chn);
//         return;
//     }
//     chn->DisableWrite();
// }

// void HandleError(Channel *chn)
// {
//     HandleClose(chn);
// }

// void HandleAny(Channel *chn)
// {
//     DBG_LOG("----------------------");
// }   

// void Acceptor(EventLoop *loop, int sockfd)
// {
//     int newfd = accept(sockfd, nullptr, nullptr);
//     Channel *newchannel = new Channel(loop, newfd);
//     newchannel->SetHandleRead(std::bind(&HandleRead, newchannel));
//     newchannel->SetHandleWrite(std::bind(&HandleWrite, newchannel));
//     newchannel->SetHandleError(std::bind(&HandleError, newchannel));
//     newchannel->SetHandleClose(std::bind(&HandleClose, newchannel));
//     newchannel->SetHandleAny(std::bind(&HandleAny, newchannel));
//     newchannel->EnableRead();
// }

// int main()
// {
//     Socket socket;
//     if (!socket.CreateServer(8080)) 
//     {
//         ERR_LOG("create server error");
//         return 0;
//     }
//     EventLoop baseloop(std::this_thread::get_id());
//     int _listensockfd = socket.Fd();
//     Channel accept_channel(&baseloop, _listensockfd);
//     accept_channel.SetHandleRead(std::bind(&Acceptor, &baseloop, _listensockfd));
//     accept_channel.EnableRead();

//     baseloop.Loop();
//     return 0;
// }


// void MessCallBack(const PtrConn &ptr, Buffer *in_buffer)
// {
//     char buffer[65535] = { 0 };
//     int ret = in_buffer->ReadAndPush(buffer, sizeof(buffer));
//     if (ret < 0)
//     {
//         ERR_LOG("inbuffer read error, buffer breakdown, close connection");
//         ptr->ReleaseConnection();
//         return;
//     }
//     DBG_LOG("recv fd : %d a message: %s", ptr->GetFd(), buffer);

//     ptr->Send(buffer, ret);
// }


// void Acceptor(EventLoop *loop, int sockfd, std::unordered_map<int, PtrConn> *mp, int *conn_id)
// {
//     int newfd = accept(sockfd, nullptr, nullptr);
    
//     PtrConn Ptr = std::make_shared<Connection>(loop, (*conn_id), newfd);
//     Ptr->SetMessageCallBack(std::bind(&MessCallBack, std::placeholders::_1, std::placeholders::_2));

//     mp->insert({*conn_id, Ptr});
//     (*conn_id)++;
// }

// int main()
// {
//     Socket socket;
//     if (!socket.CreateServer(8080)) 
//     {
//         ERR_LOG("create server error");
//         return 0;
//     }
//     std::unordered_map<int, PtrConn> mp;
//     int conn_id = 0;

//     EventLoop baseloop(std::this_thread::get_id());
//     int _listensockfd = socket.Fd();
//     Channel accept_channel(&baseloop, _listensockfd);
//     accept_channel.SetHandleRead(std::bind(&Acceptor, &baseloop, _listensockfd, &mp, &conn_id));
//     accept_channel.EnableRead();

//     baseloop.Loop();

//     return 0;
// }



void MessCallBack(const PtrConn &ptr, Buffer *in_buffer)
{
    char buffer[65535] = { 0 };
    int ret = in_buffer->ReadAndPush(buffer, sizeof(buffer));
    if (ret < 0)
    {
        ERR_LOG("inbuffer read error, buffer breakdown, close connection");
        ptr->ReleaseConnection();
        return;
    }
    DBG_LOG("recv fd : %d a message: %s", ptr->GetFd(), buffer);

    ptr->Send(buffer, ret);
}

int main()
{
    TcpServer tcpserver(8080);
    tcpserver.SetMessageCallBack(std::bind(&MessCallBack, std::placeholders::_1, std::placeholders::_2));
    tcpserver.EnableInactiveDestroy(5);
    tcpserver.CreateThread(3);
    tcpserver.Listen();
    return 0;
}



